package com.wsx.boots.auth.config;

import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSubjectFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.annotation.Validated;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Created by wangshuaixin on 17/4/23.
 */
@Configuration
public class ShiroConfiguration {

    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);

        //增加过滤器
        factoryBean.getFilters().put("statelessAuthc", statelessAuthcFilter());

        //拦截内容
        Map<String, String> filters = new LinkedHashMap<String, String>();
        filters.put("/**", "statelessAuthc");

        factoryBean.setFilterChainDefinitionMap(filters);


        return factoryBean;
    }

    /**
     * 访问控制器
     * @return
     */
    @Bean
    public StatelessAccessControlFilter statelessAuthcFilter() {
        StatelessAccessControlFilter filter = new StatelessAccessControlFilter();
        return filter;
    }

    /**
     * shiro 的安全管理器
     * 主要提供身份管理，缓存，cookie管理
     * 实际操作中主要和securityManager进行交互
     */
    @Bean
    public DefaultSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //
        securityManager.setSubjectFactory(subjectFactory());

        //
        securityManager.setSessionManager(sessionManager());

        //
        securityManager.setRealm(statelessRealm());

        //禁止使用session作为存储
        ((DefaultSessionStorageEvaluator)
        ((DefaultSubjectDAO)securityManager.getSubjectDAO())
                .getSessionStorageEvaluator())
                .setSessionStorageEnabled(false);
        return securityManager;
    }

    /**
     * 自定义的realm，实现数据验证和授权
     * @return
     */
    @Bean
    public StatelessAuthorizingRealm statelessRealm() {
        StatelessAuthorizingRealm realm = new StatelessAuthorizingRealm();
        return realm;
    }

    /**
     * subject的工厂
     * @return
     */
    @Bean
    public DefaultWebSubjectFactory subjectFactory() {
        StatelessDefaultSubjectFactory subjectFactory = new StatelessDefaultSubjectFactory();
        return subjectFactory;
    }

    /**
     * session管理器
     * @return
     */
    @Bean
    public DefaultSessionManager sessionManager() {
        DefaultSessionManager sessionManager = new DefaultSessionManager();
        sessionManager.setSessionValidationSchedulerEnabled(false);
        return sessionManager;
    }
}
